package net.caidingke.shepherd.config;

import lombok.extern.slf4j.Slf4j;
import net.caidingke.shepherd.utils.mapper.JsonMapper;
import net.caidingke.shepherd.utils.time.TimeService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @author bowen.
 */
@Aspect
@Order(5)
@Component
@Slf4j(topic = "REQUEST-TIME")
public class LogAspect {

    @Pointcut("execution(public * net.caidingke.shepherd.controller..*.*(..))")
    public void webLog() {
    }

    @Around("webLog()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = TimeService.getCurrentMillis();

        ServletRequestAttributes attributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = attributes.getRequest();

        String req =
                String.format(
                        "URL:%s|HTTP_METHOD:%s|IP:%s|CLASS_METHOD:%s|ARGS:%s",
                        request.getRequestURL().toString(),
                        request.getMethod(),
                        request.getRemoteAddr(),
                        pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName(),
                        Arrays.toString(pjp.getArgs()));

        Object ret = pjp.proceed();

        log.info(
                String.format(
                        "[request:%s];[response:%s];[spend time:%s]",
                        req, JsonMapper.toJson(ret), (TimeService.getCurrentMillis() - startTime)));
        return ret;
    }
}
